package com.netty.modbus.handler;

import com.netty.modbus.dto.DataReceiveBody;
import com.netty.modbus.dto.request.ReadBody;
import com.netty.modbus.dto.request.WriteBody;
import com.netty.modbus.dto.response.*;
import com.netty.modbus.repository.DevChannelRepository;
import com.netty.modbus.util.HexUtil;
import com.netty.modbus.util.SendCommand;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * description: RequestHandler <br>
 * date: 2021/9/30 14:51 <br>
 * @author: lwy <br>
 * @version: 1.0 <br>
 */
public abstract class InHandler extends SimpleChannelInboundHandler<ResponseBody> {
    private DevChannelRepository devChannelRepository=DevChannelRepository.getInstance();

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("异常"+cause.getMessage());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //移除设备
        ctx.channel().remoteAddress();
    }



    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ResponseBody responseBody) throws Exception {
        // 获取管道
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress().toString());
        DataReceiveBody dataReceiveBody=new DataReceiveBody();
        if(responseBody instanceof RegisterBody){
            //注册时，将序列号解析出来并与通道相关联
            byte[] data=responseBody.getDataContent();
            byte[] devNumber=new byte[20];
            System.arraycopy(data,0,devNumber,0,20);
            String devHex=HexUtil.bytesToHex(devNumber);
            String  devStr=HexUtil.hexStr2Str(devHex).trim();
            //将设备与通道对应关系存储
            devChannelRepository.setDevChannel(devStr,channel);
        }else if(responseBody instanceof ReadResponseBody){
            //获取读取的数据
            ReadResponseBody readResponseBody=(ReadResponseBody) responseBody;
            ReadBody readBody=(ReadBody)devChannelRepository.getCommand().poll();
            dataReceiveBody.setDevNumber(readBody.getDevNumber());
            dataReceiveBody.setData(readResponseBody.getData());
            dataReceiveBody.setStartAddress(readBody.getStartAddress());
            dataReceiveBody.setQuantity(readBody.getQuantity());
            readAlarmSettingData(dataReceiveBody);
        }else if(responseBody instanceof WriteResponseBody){
            //写入命令
            WriteResponseBody writeResponseBody= (WriteResponseBody)responseBody;
            WriteBody writeBody=(WriteBody) devChannelRepository.getCommand().poll();
            dataReceiveBody.setDevNumber(writeBody.getDevNumber());
            dataReceiveBody.setStartAddress(writeResponseBody.getStartAddress());
            dataReceiveBody.setQuantity(writeResponseBody.getQuantity());
            writeAlarmSettingBackData(dataReceiveBody);
        }else if(responseBody instanceof AlarmSettingBody){
            //报警设置数据上传,根据通道获取key也就是devNumber
            for(String key:devChannelRepository.getDevChannel().keySet()){
                if(devChannelRepository.getDevChannel().get(key).equals(channel)){
                    dataReceiveBody.setDevNumber(key);
                    break;
                }
            }
            dataReceiveBody.setData(responseBody.getDataContent());
            alarmSettingData(dataReceiveBody);
        }else if(responseBody instanceof DataUpBody){
            byte[] data=responseBody.getDataContent();
            byte[] devNumber=new byte[20];
            System.arraycopy(data,8,devNumber,0,20);
            String devHex=HexUtil.bytesToHex(devNumber);
            String  devStr=HexUtil.hexStr2Str(devHex).trim();
            if(!devChannelRepository.hasDev(devStr)){
                //没有该设备
                devChannelRepository.setDevChannel(devStr,channel);
            }
            dataReceiveBody.setDevNumber(devStr);
            dataReceiveBody.setData(responseBody.getDataContent());
            realTimeData(dataReceiveBody);
           /* //设备编号
            String devNumberStr="A13c610583e57d";
            //根据地址表获取读取地址位置
            String startPosHex="1231";
            //14个
            String quantity="0005";
            SendCommand.sendReadCommand(devNumberStr,startPosHex,quantity);*/
        }
        channel.write(responseBody);
    }

    /**
     * description: 报警配置数据上传
     * version: 1.0
     * date: 2021/10/11 15:32
     * @author: lwy
     *@param dataReceiveBody 接收数据
     * @return void
     */
    protected abstract void alarmSettingData(DataReceiveBody dataReceiveBody);

    /**
     * description: 读取自定义位置报警配置数据
     * version: 1.0
     * date: 2021/10/11 15:32
     * @author: lwy
     * @param dataReceiveBody 接收数据
     * @return void
     */
    protected abstract void readAlarmSettingData(DataReceiveBody dataReceiveBody);

    /**
     * description: 写自定义位置报警配置数据后反馈
     * version: 1.0
     * date: 2021/10/11 15:34
     * @author: lwy
     * @param dataReceiveBody 接收数据
     * @return void
     */
    protected abstract void writeAlarmSettingBackData(DataReceiveBody dataReceiveBody);

    /**
     * description: 实时数据上传
     * version: 1.0
     * date: 2021/10/11 15:34
     * @author: lwy
     * @param dataReceiveBody 接收数据
     * @return void
     */
    protected abstract void realTimeData(DataReceiveBody dataReceiveBody);
}
